import { Component, Vue } from 'vue-property-decorator';
import { Action } from "vuex-class";
import {
    isEmpty, isEqual, find
} from 'lodash'
/**
 * 这是一个目标选项卡mixin类
 *
 * mixinTabPage
 *
 * 通常用于选项卡页面的一些处理
 * 需通过go方法进入视图才能生效
 * @param {Boolean} isEdit 是否修改模式，请勿修改
 * @Functinon closeTab 关闭选项卡并返回来源菜单
 *
 //路由配置如下
{
    name: "routerName",
    path: '/routerName/:id',
    component: () => import('viewPath')
}
// 列表页调用方式
this.$router.push({
        name:'routerName',
        params: {
            // 数据主键，必须
            id: id,
            // 自定义标题，用于tab导航栏显示标题
            title: title,
            // 是否修改模式
            // 提交表单会根据此配置调用不同的方法去提交数据
            // true 修改，调用this.itemEdit
            // false 新增，调用this.itemAdd
            isEdit: true,
            // 想传递的参数
            data:{}
        }
});
// 或者
this.go('routerName',{
            // 数据主键，必须
            id: id,
            // 自定义标题，用于tab导航栏显示标题
            title: title,
            // 是否修改模式
            // 提交表单会根据此配置调用不同的方法去提交数据
            // true 修改，调用this.itemEdit
            // false 新增，调用this.itemAdd
            isEdit: true,
            // 想传递的参数
            data:{}
        });
// 新增逻辑
// data 接收的数据
addInit(data: any) {
}
// 编辑逻辑
// id 数据主键
// data 想传递的参数
editInit({ id, data }: any) {
}
 *
 *
 * @export
 * @class mixinTabForm
 * @extends {Vue}
 */

@Component({})
export class mixinTabPage extends Vue {
    // 关闭当前页面
    @Action("corePage/close") pageClose: any;

    /**
     * 关闭选项卡并返回来源菜单
     *
     * @memberof mixinTabNav
     */
    goBack() {
        this.closeTab();
    }

    /**
     * 关闭选项卡并返回来源菜单,可设置isUp
     *
     * @param {number} [isUp=0] 来源菜单页是否更新数据 0 否 1 新增 2 修改
     * @memberof mixinTabNav
     */
    closeTab(isUp: number = 0) {
        const me = this as any;
        me.pageClose({
            tagName: me.$route.fullPath,
            basePath: me.baseUrl,
            isUp: isUp
        })
    }

    // 通过id设置页面缓存
    @Action("coreDb/pageSetById") pageSetById: any;
    // 通过id读取页面缓存
    @Action("coreDb/pageGetById") pageGetById: any;
    // 是否修改模式
    // 提交表单会根据此配置调用不同的方法去提交数据
    // true 修改，调用this.itemEdit
    // false 新增，调用this.itemAdd
    isEdit: boolean = false;
    // 是否详情模式
    // 此模式一般为只读状态
    isInfo: boolean = false;
    // 是否初始化视图
    isInit: boolean = true;
    // 来源菜单
    baseUrl: string = "";
    // 标题
    title: string = "";

    /**
     * 获取路由数据后处理
     *
     * @param {*} data
     * @memberof mixinTabForm
     */
    onLoad({ id, isEdit, isInfo, data, baseUrl, title }: any) {
        const me = this as any;
        me.isEdit = isEdit;
        me.isInfo = isInfo;
        // 记录来源菜单
        me.baseUrl = baseUrl;
        // 设置标题
        me.title = title;
        if (!isEdit) {
            // 新增逻辑
            me.addInit && me.addInit(data);
        } else {
            // 编辑逻辑
            me.editInit && me.editInit({ id, data });
        }
    }

    submitFormSuccess(data: any) {
        const me = this as any;
        // 检查是否有successAfter方法，如果有就执行
        me.successAfter && me.successAfter(data);
        me.closeTab(me.isEdit ? 2 : 1);
    }


    /**
      * 初始化时获取路由参数，保证页面刷新也能获取到值
      *
      * @memberof mixinTabForm
      */
    created() {
        // console.log('created')
        this.loadParams();
    }

    /**
      * 第一次进入或从其他组件对应路由进入时触发
      * 同一组件对应的多个路由间切换时不会触发
      *
      * @param {*} to
      * @param {*} from
      * @param {*} next
      */
    beforeRouteEnter(to: any, from: any, next: any) {
        next((instance: any) => {
            // console.log('beforeRouteEnter')
            // 通过状态码保证初始化时不会重复执行
            if (!instance.isInit) {
                // 根据主键获取页面缓存
                instance.loadParams();
            }
        });
    }

    /**
     *
     * 根据主键获取页面参数
     * @memberof mixinTabForm
     */
    loadParams() {
        // console.log('loadParams')
        const me = this as any,
            // 当前路由的参数
            params = me.$route.params, id = params.id;
        // 根据主键获取页面缓存
        me.pageGetById({ id: id }).then((data: any) => {
            // console.log(data, me.isInit)
            if (me.isInit) {
                // 初始化时
                if (!isEmpty(data)) {
                    // 页面刷新时可以获取到缓存参数
                    me.onLoad(data);
                } else {
                    // 如果缓存不存在则直接返回路由参数
                    me.setDataAndLoad(params, id);
                }
                me.isInit = false;
            } else if (!isEqual(data, params)) {
                // console.log(data, params)
                // 非初始化时，如果路由参数和缓存数据不一致，保存路由参数并并触发onLoad，这样保证页面数据及时更新
                me.setDataAndLoad(params, id)
            }
        });
    }

    /**
     * 保存数据并触发onLoad
     *
     * @param {*} data 数据
     * @param {*} id 主键
     * @memberof mixinTabForm
     */
    setDataAndLoad(data: any, id: any) {
        const me = this as any;
        // 如果缓存不存在则直接返回路由参数
        me.pageSetById({ data, id })
        me.onLoad(data)
    }

    /**
     * 根据数据查询label
     *
     * @param {*} data 数据
     * @param {string} key 字段名称
     * @param {*} value 值
     * @return {*}
     * @memberof mixinTabPage
     */
    queryLabel(data: any, key: string, value: any) {
        if (data.length && value) {
            const item = find(data, {
                value: value.toString()
            });
            return item ? item.label : "";
        }
        return "";
    }

    // 是否有滚动条
    isScroll: boolean = false;
    // 如果有滚动条则浮动显示操作栏
    get scrollCls() {
        return this.isScroll ? 'scroll-el' : '';
    }
    /**
     * 视图更新是检查是否有滚动条
     *
     * @memberof mixinTabForm
     */
    mounted() {
        this.checkScroll();
    }
    /**
     * 检查是否有滚动条
     * 如果有则浮动显示操作栏
     * 通常由updated触发，有时候需要手动触发
     *
     * @memberof mixinTabForm
     */
    checkScroll() {
        const me = this as any;
        me.$nextTick(() => {
            const el = me.$el.parentNode;
            if (el) {
                me.isScroll = el.scrollHeight > el.offsetHeight
                // console.log(me.isScroll);
            }
        });
    }
}